package com.travel.server.manager.impl.command.project;

import com.travel.common.CommonConstant;
import com.travel.common.util.CollectionUtil;
import com.travel.common.util.CommonUtil;
import com.travel.server.manager.dto.request.project.QueryProjectListRequest;
import com.travel.server.manager.dto.response.project.QueryProjectListResponse;
import com.travel.server.manager.dto.response.project.QueryProjectListResponse.ProjectItem;
import com.travel.server.manager.impl.command.AbstractCommand;
import com.travel.server.manager.impl.dal.PageDto;
import com.travel.server.manager.impl.dal.ProjectDal;
import com.travel.server.manager.impl.dal.ProjectDal.ProjectParam;
import com.travel.server.manager.impl.dal.SpecialDal;
import com.travel.server.manager.impl.dal.SpecialDal.SpecialParam;
import com.travel.server.manager.model.ProjectInfo;
import com.travel.server.manager.model.ProjectSpecial;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;

/**
 * @Author: LiZhenhui
 * @Date: 2018/10/18 16:19
 * @Desc:
 */
@Component
@Slf4j
public class QueryProjectListCommand extends AbstractCommand<QueryProjectListRequest, QueryProjectListResponse> {

    @Autowired
    private SpecialDal specialDal;

    @Autowired
    private ProjectDal projectDal;

    @Override
    protected void checkInput(QueryProjectListRequest request) {
        checkPageInput(request);
    }

    @Override
    public QueryProjectListResponse handle(QueryProjectListRequest request) {
        checkInput(request);

        QueryProjectListResponse response = new QueryProjectListResponse();

        ProjectParam param = new ProjectParam();

        //查天数对应的projectId
        if(StringUtils.isNotBlank(request.getDays())){
            SpecialParam specialParam = new SpecialParam();
            specialParam.setDays(request.getDays());
            List<ProjectSpecial> specialList = specialDal.selectByExample(specialParam);
            if(CollectionUtil.isEmpty(specialList)){
                return response;
            }
            List<Integer> projectIdList = new ArrayList<>();
            for(ProjectSpecial projectSpecial : specialList){
                projectIdList.add(projectSpecial.getProjectId());
            }
            param.setIdList(projectIdList);
        }
        makeParam(request, param);

        PageDto<ProjectInfo> pageDto = projectDal.select(param);

        List<ProjectInfo> list = pageDto.getList();
        List<ProjectItem> projectItemList = new ArrayList<>();
        if(!CollectionUtil.isEmpty(list)){
            //天数与项目信息不在同一张表，为节省时间，使用id列表查询
            List<Integer> projectIdList = new ArrayList<>();
            for(ProjectInfo projectInfo : list){
                projectIdList.add(projectInfo.getId());
            }
            SpecialParam specialParam = new SpecialParam();
            specialParam.setProjectIdList(projectIdList);
            List<ProjectSpecial> specialList = specialDal.selectByExample(specialParam);
            //用map的key唯一性保存
            Map<Integer, List<String>> daysMap = new HashMap<>();
            Map<Integer, List<Long>> priceMap = new HashMap<>();
            if(!CollectionUtil.isEmpty(specialList)){
                for(ProjectSpecial projectSpecial : specialList){
                    List<String> daysList = daysMap.get(projectSpecial.getProjectId());
                    if(daysList == null){
                        daysList = new ArrayList<>();
                    }
                    daysList.add(projectSpecial.getDays());
                    daysMap.put(projectSpecial.getProjectId(), daysList);

                    List<Long> priceList = priceMap.get(projectSpecial.getProjectId());
                    if(priceList == null){
                        priceList = new ArrayList<>();
                    }
                    if(projectSpecial.getPrice() != null) {
                        priceList.add(projectSpecial.getPrice());
                        priceMap.put(projectSpecial.getProjectId(), priceList);
                    }
                }
            }
            projectItemList = makeList(list, daysMap, priceMap);
        }
        response.setProjectList(projectItemList);
        response.setTotalNum(pageDto.getTotal());

        return response;
    }

    private void makeParam(QueryProjectListRequest request, ProjectParam param){
        if(StringUtils.isNotBlank(request.getCountry())){
            param.setCountry(request.getCountry());
        }
        if(StringUtils.isNotBlank(request.getType())){
            param.setType(request.getType());
        }
        if(StringUtils.isNotBlank(request.getName())){
            param.setName(request.getName());
        }
        if(request.getStartPrice() != null){
            BigDecimal bigDecimal = CommonUtil.yuanToFen(request.getStartPrice());
            param.setStartPrice(bigDecimal.longValue());
        }
        if(request.getEndPrice() != null){
            BigDecimal bigDecimal = CommonUtil.yuanToFen(request.getEndPrice());
            param.setEndPrice(bigDecimal.longValue());
        }
        if(StringUtils.isNotBlank(request.getProject())){
            param.setProjectGroup(request.getProject());
        }
        if(StringUtils.isNotBlank(request.getStock())){
            param.setStock(Integer.parseInt(request.getStock()));
        }
        param.setOffset(request.getOffset());
        param.setLimit(request.getLimit());
    }

    private List<ProjectItem> makeList(List<ProjectInfo> projectInfoList, Map<Integer, List<String>> daysMap, Map<Integer, List<Long>> priceMap){
        List<ProjectItem> list = new ArrayList<>();
        for(ProjectInfo projectInfo : projectInfoList) {
            ProjectItem item = new ProjectItem();
            item.setCountry(projectInfo.getCountry());
            item.setCreateTime(projectInfo.getCreateTime());
            item.setId(projectInfo.getId());
            item.setPicUrl(projectInfo.getProjectPicUrl());
            item.setName(projectInfo.getName());
            List<Long> priceList = priceMap.get(projectInfo.getId());
            if(!CollectionUtil.isEmpty(priceList)){
                if(priceList.size() == 1){
                    item.setPrice(CommonUtil.fenToYuan(priceList.get(0)).toString());
                }else{
                    item.setPrice(getPrice(priceList));
                }
            }
            item.setProject(projectInfo.getProjectGroup());
            item.setStock(projectInfo.getStock() + CommonConstant.EMPTY_STR);
            item.setType(projectInfo.getProjectType());
            item.setDays(daysMap.get(projectInfo.getId()));
            list.add(item);
        }
        return list;
    }

    private String getPrice(List<Long> priceList){
        Long[] array = sort(priceList);
        if(array[0].equals(array[array.length - 1])){
            return CommonUtil.fenToYuan(array[0]).toString();
        }
        return CommonUtil.fenToYuan(array[0]).toString() + " - " + CommonUtil.fenToYuan(array[array.length - 1]).toString();
    }

    private Long[] sort(List<Long> priceList){
        Long[] array = new Long[priceList.size()];
        for(int i = 0; i < priceList.size(); i++){
            array[i] = priceList.get(i);
        }
        //外层循环控制排序趟数
        for(int i=0;i<array.length-1;i++){
            //内层循环控制每一趟排序多少次
            for(int j=0;j<array.length-1-i;j++){
                if(array[j]>array[j+1]){
                    Long temp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=temp;
                }
            }
        }
        return array;
    }
}
